package com.github.tommas.admintpl.bean.filestorage;

import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Random;

public abstract class AbstractFileStorage implements FileStorage {
    private static final Random random;

    static {
        random = new Random();
    }

    abstract protected boolean hasDuplicateStorageId(String storageId);
    abstract protected void doStore(InputStream inputStream, String storageId, String filename);

    @Override
    public String store(InputStream inputStream, String filename) {
        String storageId = generateStorageId(filename);
        if (hasDuplicateStorageId(storageId)) {
            throw new RuntimeException(String.format("StorageId: %s already exist", storageId));
        }

        doStore(inputStream, storageId, filename);

        return storageId;
    }

    protected String generateStorageId(String filename) {
        byte[] bytes = new byte[16];
        random.nextBytes(bytes);
        Date now = new Date();
        String s = now.getTime() + filename + new String(bytes);
        return hashString(s, "SHA-256");
    }

    private String hashString(String str, String algorithm) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException nsae) {
            throw new InternalError(String.format("Algorithm: %s not supported", algorithm), nsae);
        }

        byte[] hashBytes = digest.digest(str.getBytes());
        StringBuilder hexString = new StringBuilder();
        for (byte b : hashBytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }

        return hexString.toString();
    }
}
